/**
 *  在后台管理系统中，有很多的表格，都是要动态生成+分页+搜索的
 *  逻辑几乎是一样的
 *      1. 分页获取数据
 *      2. 切换当前页+当前的页容量
 *      3. 进行搜索
 *
 *  把这部分逻辑封装起来，然后在后面进行调用的时候就方便了
 *
 *  思考：
 *      现在其实就是在封装函数
 *          封装函数有两个要点： 参数 , 返回值
 *              哪些会变的，作为参数
 *              哪些是要对外提供的，作为返回值
 *
 *
 *      哪些会变：
 *          请求的接口(方法)，搜索的参数
 *      对外提供哪些：
 *          表格需要的数据(请求回来的数据)
 */

import { reactive, ref, toRefs, UnwrapNestedRefs } from 'vue';

// 封装的原则： 尽可以让外面调用要简单，尽可以让复用的代码放到封装好的代码里面
export function useTable<T extends { list: any; total: number }, S = object>(
    requestApi: (params: any) => RPS<T>,
    searchParams?: UnwrapNestedRefs<S>
) {
    const query = reactive({
        pageSize: 10,
        pageNum: 1,
    });

    // 现在我们希望这个数据发生变化，视图也跟着刷新 --> 把这个数据变成 响应式数据
    const tableData = ref<T['list']>([]);
    const total = ref(0);

    // 1. 肯定是先请求
    async function fetchData() {
        const res = await requestApi({
            pageSize: query.pageSize,
            pageNum: query.pageNum,
            ...searchParams,
        });
        // res 一定是 {code:number, data : { list:[],total:number , ... } , message : string;}
        // 现在封装起来的是调用 请求数据的 方法已经被调用， 把 外面表格需要的数据 给到
        tableData.value = res.data.list;
        total.value = res.data.total;
    }
    fetchData();

    // 分页组件的pageSize变化的回调
    const pageSizeChange = () => {
        fetchData();
    };
    // 分页组件的 currentPage 变化的回调
    const pageNumChange = () => {
        fetchData();
    };

    // 搜索功能
    const search = () => {
        fetchData();
    };
    return {
        tableData,
        ...toRefs(query), /// toRefs 的作用是 把 里面的每个属性都变成 ref 数据，让里面的每个数据解构之后不会失去响应式特性
        total,
        pageSizeChange,
        pageNumChange,

        search,
    };
}
